package com.etbsms.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Implements the generic CRUD data access operations using Hibernate.
 * <p>
 * To write a DAO, subclass and parameterize this class with your entity. Of
 * course, assuming that you have a traditional 1:1 appraoch for Entity:DAO
 * design.
 * 
 */
public abstract class GenericDAOImpl<T, ID extends Serializable> {
	
	@Autowired
	public SessionFactory sessionFactory;
	
	
	private Class<T> persistentClass;

	@SuppressWarnings("unchecked")
	public GenericDAOImpl() {
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	public Class<T> getPersistentClass() {
		return persistentClass;
	}

	public boolean saveOrUpdate(T entity) {
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		try{		
			session.saveOrUpdate(entity);
			tx.commit();
			return true;
		}catch(Exception e){
			e.printStackTrace();
			tx.rollback();
			return false;
		}finally{
			session.close();
		}		
	}

	@SuppressWarnings("unchecked")
	public T get(ID id) {
		try{
			Session session = sessionFactory.openSession();
			T t = (T)session.get(getPersistentClass(), id);
			session.close();
			return t;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
	
	public boolean save(T entity) {
		boolean result = false;
		Session session = sessionFactory.openSession();		
		try{
			Transaction tx = session.beginTransaction();
			session.save(entity);			
			tx.commit();		
			result = true;
		}catch(Exception e){
			e.printStackTrace();
		}
		session.close();
		return result;
	}
	
	public boolean update(T entity) {
		boolean result = false;
		Session session = sessionFactory.openSession();		
		try{
			Transaction tx = session.beginTransaction();
			session.update(entity);			
			tx.commit();		
			result = true;
		}catch(Exception e){
			e.printStackTrace();
		}
		session.close();
		return result;
	}
	
}
